import java.util.ArrayList;
import java.util.Random;

public class Player {
	private Random rand;
	private ArrayList<String> actions;
	private int Spd; 
	private int Str;
	private int Int;
	private int Hp;
	private int Mp;
	private int Def;
	private int Mdef;
	private int curHp;
	private int curMp;
	private int exp;
	private int level;
	private int gold;
	private Equip helm;
	private Equip armor;
	private Equip weapon;
	private String name;
	private Inventory inv;

	public Player(String name){
		initialize(name, null);
		setActions(new ArrayList<String>());
	}

	public Player(String name, int[] stats, Equip helm, Equip armor, Equip weapon, ArrayList<String> a, Inventory inv){
		if(a != null)
			setActions(new ArrayList<String>(a));
		this.inv = inv;
		equipHelm(helm);
		equipArmor(armor);
		equipWeapon(weapon);
		initialize(name, stats);
	}
	public Player(Player player) {
		actions = new ArrayList<String>(player.getActions());
		Spd = new Integer(player.Spd);
		Str = new Integer(player.Str);
		Int = new Integer(player.Int);
		Hp = new Integer(player.Hp);
		Mp = new Integer(player.Mp);
		Def = new Integer(player.Def);
		Mdef = new Integer(player.Mdef);
		curHp = new Integer(player.curHp);
		curMp = new Integer(player.curMp);
		exp = new Integer(player.exp);
		level = new Integer(player.level);
		gold = new Integer(player.gold);
		helm = new Equip(player.helm, 0);
		armor = new Equip(player.armor, 0);
		weapon = new Equip(player.weapon, 0);
		name = new String(player.name);
		inv = player.getInv();
	}

	private void initialize(String name, int[] stats) {
		rand = new Random();
		this.name = name;
		if(stats == null){
			setGold(0);
			exp = 0;
			level = 1;
			int points = 10;
			int temp = nextRand(points, 5);
			points -= temp;
			setHp(temp + 10);
			setCurHp(getHp());
			temp = nextRand(points, 5);
			points -= temp;
			setMp(temp + 8);
			setCurMp(getMp());
			temp = 0;
			if(points > 0){
				temp = nextRand(points, 5);
				points -= temp;
			}
			setMdef(temp + 2);
			temp = 0;
			if(points > 0){
				temp = nextRand(points, 5);
				points -= temp;
			}
			setDef(temp + 2);
			temp = 0;
			if(points > 0){
				temp = nextRand(points, 2);
				points -= temp;
			}
			setStr(temp + 3);
			temp = 0;
			if(points > 0){
				temp = nextRand(points, 2);
				points -= temp;
			}
			setInt(temp + 3);
			temp = 0;
			if(points > 0)
				temp += points;
			setSpeed(temp + 2);
			inv = new Inventory();
			actions = new ArrayList<String>();
		}
		else{
			level = stats[0];
			exp = stats[1];
			Hp = stats[2];
			curHp = stats[3];
			Mp = stats[4];
			curMp = stats[5];
			Mdef = stats[6];
			Def = stats[7];
			Str = stats[8];
			Int = stats[9];
			Spd = stats[10];
			setGold(stats[11]);
		}
	}

	public Inventory getInv(){
		return inv;
	}

	public void equipHelm(Equip equip) {
		if(equip != null && equip.getType() == Equip.Type.Helm)
			helm = equip;
	}

	public void equipArmor(Equip equip) {
		if(equip != null && equip.getType() == Equip.Type.Armor)
			armor = equip;
	}

	public void equipWeapon(Equip equip) {
		if(equip != null && equip.getType() == Equip.Type.Weapon)
			weapon = equip;
	}

	public Equip getHelm(){
		return helm;
	}

	public Equip getArmor(){
		return armor;
	}

	public Equip getWeapon(){
		return weapon;
	}

	private int nextRand(int remain, int cap){
		int temp = rand.nextInt(cap) + 1;
		if(temp > remain)
			return nextRand(remain, cap);
		else return temp;
	}

	public int getStr() {
		return Str + (helm != null ? helm.getStr() : 0) + (armor != null ? armor.getStr() : 0)
				+ (weapon != null ? weapon.getStr() : 0);
	}

	public void setStr(int str) {
		Str = str;
	}

	public int getInt() {
		return Int + (helm != null ? helm.getInt() : 0) + (armor != null ? armor.getInt() : 0)
				+ (weapon != null ? weapon.getInt() : 0);
	}

	public void setInt(int _int) {
		Int = _int;
	}

	public int getHp() {
		return Hp + (helm != null ? helm.getHp() : 0) + (armor != null ? armor.getHp() : 0)
				+ (weapon != null ? weapon.getHp() : 0);
	}

	public int getBaseHp(){
		return Hp;
	}

	public void setHp(int hp) {
		if(curHp > hp)
			curHp = hp;
		Hp = hp;
	}

	public int getMp() {
		return Mp + (helm != null ? helm.getMp() : 0) + (armor != null ? armor.getMp() : 0)
				+ (weapon != null ? weapon.getMp() : 0);
	}

	public int getBaseMp(){
		return Mp;
	}

	public void setMp(int mp) {
		if(curMp > mp)
			curMp = mp;
		Mp = mp;
	}

	public int getDef() {
		return Def + (helm != null ? helm.getDef() : 0) + (armor != null ? armor.getDef() : 0)
				+ (weapon != null ? weapon.getDef() : 0);
	}

	public void setDef(int def) {
		Def = def;
	}

	public int getMdef() {
		return Mdef + (helm != null ? helm.getMdef() : 0) + (armor != null ? armor.getMdef() : 0)
				+ (weapon != null ? weapon.getMdef() : 0);
	}

	public void setMdef(int mdef) {
		Mdef = mdef;
	}

	public int getCurHp() {
		return curHp;
	}

	public int getSpeed(){
		return Spd;
	}

	public void setSpeed(int speed){
		this.Spd = speed;
	}

	public void setCurHp(int curHp) {
		this.curHp = curHp;
	}

	public int getCurMp() {
		return curMp;
	}

	public void setCurMp(int curMp) {
		this.curMp = curMp;
	}

	public int getExp() {
		return exp;
	}

	public void levelUp() {
		level++;
	}

	public int getLevel(){
		return level;
	}

	public String getName() {
		return name;
	}

	/**
	 * @return the actions
	 */
	public ArrayList<String> getActions() {
		return actions;
	}

	/**
	 * @param actions the actions to set
	 */
	public void setActions(ArrayList<String> actions) {
		this.actions = actions;
	}

	public void printSkills(){
		System.out.println("Spd is " + Spd);
		System.out.println("Str is " + Str);
		System.out.println("Int is " + Int);
		System.out.println("Hp is " + Hp);
		System.out.println("Mp is " + Mp);
		System.out.println("Def is " + Def);
		System.out.println("Mdef is " + Mdef);
	}

	public void setExp(int nextExp) {
		exp = nextExp;
	}

	public int getGold() {
		return gold;
	}

	public void setGold(int gold) {
		this.gold = gold;
	}

	public int getBaseInt() {
		return Int;
	}

	public int getBaseStr() {
		return Str;
	}

	public int getBaseMdef() {
		return Mdef;
	}

	public int getBaseDef() {
		return Def;
	}
}
